package cn.lg.soar.message.service;

import cn.lg.soar.common.util.listener.SpringUtils;
import cn.lg.soar.message.event.WebSocketCloseEvent;
import cn.lg.soar.message.event.WebSocketErrorEvent;
import cn.lg.soar.message.event.WebSocketMessageEvent;
import cn.lg.soar.message.event.WebSocketOpenEvent;
import cn.lg.soar.mvc.manager.AbstractClientInfoManager;
import cn.lg.soar.mvc.manager.IClientNoticeService;
import cn.lg.soar.mvc.model.ClientInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.Session;
import java.io.IOException;
import java.util.Collection;

/**
 * websocket服务
 * @author luguoxiang
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class WebSocketManager extends AbstractClientInfoManager<Session> implements IClientNoticeService {
    protected static final Logger logger = LoggerFactory.getLogger(WebSocketManager.class);
    private final static int LENGTH = JOIN.length();

    @Override
    public Collection<Long> sendMsgByUser(String topic, String message, Collection<Long> userIds) {
        return sendMsgByUser(topic + JOIN + message, userIds);
    }

    @Override
    public boolean sendMsgByClient(String topic, String message, String clientId) {
        return sendMsgByClient(topic + JOIN + message, clientId);
    }

    /**
     * 广播消息
     * @param message 消息
     */
    @Override
    public Collection<Long> sendMsgAll(String topic, String message) {
        return sendMsgAll(topic + JOIN + message);
    }

    @Override
    protected boolean doSendMsg(Session client, String message) {
        try {
            client.getBasicRemote().sendText(message);
            return true;
        } catch (IOException e) {
            logger.error("sse消息发送失败", e);
            return false;
        }
    }

    public void onOpen(Long userId, String clientId, Session session) {
        session.setMaxIdleTimeout(600_000L);
        put(userId, clientId, session);
        sendMsgAll("online", String.valueOf(size()));
        SpringUtils.publishEvent(new WebSocketOpenEvent(clientId, size()));
    }

    public void onMessage(String message, Session session) {
        logger.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
        int index = message.indexOf(JOIN);
        if (index == -1) {
            return;
        }
        String topic = message.substring(0, index);
        message = message.substring(index + LENGTH);
        SpringUtils.publishEvent(new WebSocketMessageEvent(getClientId(session), topic, message));
    }

    public void onClose(Session session) {
        ClientInfo<Session> clientInfo = remove(session);
        sendMsgAll("online", String.valueOf(size()));
        if (clientInfo != null) {
            SpringUtils.publishEvent(new WebSocketCloseEvent(clientInfo.getClientId(), size()));
        }
    }

    public void onError(Session session, Throwable error) {
        logger.error("websocket发生错误", error);
        SpringUtils.publishEvent(new WebSocketErrorEvent(getClientId(session), error));
    }
}
